home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume17 / pax / part02 < prev    next >
Encoding:
Internet Message Format  |  1989-02-02  |  54.8 KB

  1. Subject:  v17i075:  Usenix/IEEE POSIX replacement for TAR and CPIO, Part02/06
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4.  
  5. Submitted-by: Mark H. Colburn <mark@jhereg.jhereg.mn.org>
  6. Posting-number: Volume 17, Issue 75
  7. Archive-name: pax/part02
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line, then unpack
  11. # it by saving it into a file and typing "sh file".  To overwrite existing
  12. # files, type "sh file -c".  You can also feed this as standard input via
  13. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  14. # will see the following message at the end:
  15. #        "End of archive 2 (of 6)."
  16. # Contents:  cpio.1 create.c func.h link.c names.c replace.c ttyio.c
  17. #   warn.c
  18. # Wrapped by mark@jhereg on Tue Dec 27 19:37:38 1988
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f cpio.1 -a "${1}" != "-c" ; then 
  21.   echo shar: Will not over-write existing file \"cpio.1\"
  22. else
  23. echo shar: Extracting \"cpio.1\" \(6231 characters\)
  24. sed "s/^X//" >cpio.1 <<'END_OF_cpio.1'
  25. X.\" $Id: cpio.1,v 1.1 88/12/23 18:02:04 mark Rel $
  26. X.TH CPIO 1 "USENIX Association" ""
  27. X.SH NAME
  28. Xcpio \- copy file archives in and out
  29. X.SH SYNOPSIS
  30. X.B cpio
  31. X.BR \-o [ Bacv ]
  32. X.br
  33. X.B cpio
  34. X.BR \-i [ Bcdfmrtuv ]
  35. X.RI [ pattern... ]
  36. X.br
  37. X.B cpio
  38. X.BR \-p [ adlmruv ]
  39. X.I directory
  40. X.SH DESCRIPTION
  41. XThe
  42. X.B cpio
  43. Xutility produces and reads files in the format specified by the
  44. X.B cpio
  45. X.B "Archive/Interchange File Format"
  46. Xspecified in
  47. X.IR "IEEE Std. 1003.1-1988" .
  48. X.PP
  49. XThe
  50. X.B "cpio -i"
  51. X(copy in) utility extracts files from the standard input, which is
  52. Xassumed to be the product of a previous
  53. X.B "cpio -o" .
  54. XOnly files with names that match
  55. X.I patterns
  56. Xare selected.
  57. XMultiple
  58. X.I patterns
  59. Xmay be specified and if no
  60. X.I patterns
  61. Xare specified, the default for
  62. X.I patterns
  63. Xis \*, selecting all files.
  64. XThe extracted files are conditionally created and copied into the
  65. Xcurrent directory, and possibly any levels below, based upon the
  66. Xoptions described below and the permissions of the files will be those
  67. Xof the previous
  68. X.B "cpio -o" .
  69. XThe owner and group of the files will be that of the current user
  70. Xunless the user has appropriate privileges, which causes
  71. X.B cpio
  72. Xto retains the owner and group of the files of the previous
  73. X.B "cpio -o" .
  74. X.PP
  75. XThe 
  76. X.B "cpio -p"
  77. X(pass) utility reads the standard input to obtain a list of path names
  78. Xof files that are conditionally created and copied into the
  79. Xdestination
  80. X.I directory 
  81. Xbased upon the options described below.
  82. X.PP
  83. XIf an error is detected, the cause is reported and the
  84. X.B cpio
  85. Xutility will continue to copy other files.
  86. X.B cpio
  87. Xwill skip over any unrecognized files which it encounters in the archive.
  88. X.PP
  89. XThe following restrictions apply to the 
  90. X.B cpio
  91. Xutility:
  92. X.IP 1 .25i
  93. XPathnames are restricted to 256 characters.
  94. X.IP 2 .25i
  95. XAppropriate privileges are required to copy special files.
  96. X.IP 3 .25i
  97. XBlocks are reported in 512-byte quantities.
  98. X.SS Options
  99. XThe following options are available:
  100. X.TP .5i
  101. X.B \-B
  102. XInput/output is to be blocked 5120 bytes to the record.
  103. XCan only be used with
  104. X.B "cpio -o" 
  105. Xor
  106. X.B "cpio -i"
  107. Xfor data that is directed to or from character special files.
  108. X.TP .5i
  109. X.B \-a
  110. XReset access times of input files after they have been copied.
  111. XWhen the
  112. X.B \-l
  113. Xoption is also specified, the linked files do not have their access
  114. Xtimes reset.
  115. XCan only be used with
  116. X.B "cpio -o"
  117. Xor
  118. X.B "cpio -i" .
  119. X.TP .5i
  120. X.B \-c
  121. XWrite header information in ASCII character for for portability.
  122. XCan only be used with
  123. X.B "cpio -i"
  124. Xor
  125. X.B "cpio -o" .
  126. XNote that this option should always be used to write portable files.
  127. X.TP .5i
  128. X.B \-d
  129. XCreates directories as needed.
  130. XCan only be used with 
  131. X.B "cpio -i" 
  132. Xor
  133. X.B "cpio -p" .
  134. X.TP .5i
  135. X.B \-f
  136. XCopy in all files except those in
  137. X.I patterns .
  138. XCan only be used with
  139. X.B "cpio -i" .
  140. X.TP .5i
  141. X.B \-l
  142. XWhenever possible, link files rather than copying them.
  143. XCan only be used with 
  144. X.B "cpio -p" .
  145. X.TP .5i
  146. X.B \-m
  147. XRetain previous modification times.
  148. XThis option is ineffective on directories that are being copied.
  149. XCan only be used with
  150. X.B "cpio -i" 
  151. Xor
  152. X.B "cpio -p" .
  153. X.TP .5i
  154. X.B \-r
  155. XInteractively rename files.
  156. XThe user is asked whether to rename
  157. X.I pattern
  158. Xeach invocation.
  159. XRead and write permissions for
  160. X.B "/dev/tty"
  161. Xare required for this option.
  162. XIf the user types a null line, the file is skipped.
  163. XShould only be used with
  164. X.B "cpio -i"
  165. Xor
  166. X.B "cpio -o" .
  167. X.TP .5i
  168. X.B \-t
  169. XPrint a table of contents of the input.
  170. XNo files are created.
  171. XCan only be used with
  172. X.B "cpio -i" .
  173. X.TP .5i
  174. X.B \-u
  175. XCopy files unconditionally; usually an older file will not replace a
  176. Xnew file with the same name.
  177. XCan only be used with
  178. X.B "cpio -i"
  179. Xor
  180. X.B "cpio -p" .
  181. X.TP .5i
  182. X.B \-v
  183. XVerbose: cause the names of the affected files to be printed.
  184. XCan only be used with
  185. X.B "cpio -i" .
  186. XProvides a detailed listing when used with the 
  187. X.B \-t
  188. Xoption.
  189. X.SS Operands
  190. XThe following operands are available:
  191. X.TP 1i
  192. X.I patterns
  193. XSimple regular expressions given in the name-generating notation of the
  194. Xshell.
  195. X.TP 1i
  196. X.I directory
  197. XThe destination directory.
  198. X.SS "Exit Status"
  199. XThe
  200. X.B cpio
  201. Xutility exits with one of the following values:
  202. X.TP .5i
  203. X0
  204. XAll input files were copied.
  205. X.TP .5i
  206. X2
  207. XThe utility encountered errors in copying or accessing files or
  208. Xdirectories.
  209. XAn error will be reported for nonexistent files or directories, or
  210. Xpermissions that do not allow the user to access the source or target
  211. Xfiles.
  212. X.SS
  213. XIt is important to use the
  214. X.B "-depth"
  215. Xoption of the
  216. X.B find
  217. Xutility to generate pathnames for 
  218. X.B cpio .
  219. XThis eliminates problems
  220. X.B cpio
  221. Xcould have trying to create files under read-only directories.
  222. X.PP
  223. XThe following command:
  224. X.RS
  225. Xls | cpio -o > ../newfile
  226. X.RE
  227. Xcopies out the files listed by the 
  228. X.B ls
  229. Xutility and redirects them to the file
  230. X.B newfile .
  231. X.PP
  232. XThe following command:
  233. X.RS
  234. Xcat newfile | cpio -id "memo/al" "memo/b*"
  235. X.RE
  236. Xuses the output file
  237. X.B newfile
  238. Xfrom the
  239. X.B "cpio -o"
  240. Xutility, takes those files that match the patterns
  241. X.B "memo/al"
  242. Xand
  243. X.B "memo/b*" ,
  244. Xcreates the directories below the current directory, and places the
  245. Xfiles in the appropriate directories.
  246. X.PP
  247. XThe command
  248. X.RS
  249. Xfind . -depth -print | cpio -pdlmv newdir
  250. X.RE
  251. Xtakes the file names piped to it from the
  252. X.B find
  253. Xutility and copies or links those files to another directory
  254. Xnamed
  255. X.B newdir ,
  256. Xwhile retaining the modification time.
  257. X.SH FILES
  258. X.TP 1i
  259. X/dev/tty
  260. Xused to prompt the user for information when the
  261. X.B \-i 
  262. Xor 
  263. X.B \-r
  264. Xoptions are specified.
  265. X.SH "SEE ALSO"
  266. Xfind(1), pax(1), tar(1), cpio(5), tar(5)
  267. X.SH COPYRIGHT
  268. XCopyright (c) 1989 Mark H. Colburn.  
  269. X.br
  270. XAll rights reserved.
  271. X.PP
  272. XRedistribution and use in source and binary forms are permitted
  273. Xprovided that the above copyright notice is duplicated in all such 
  274. Xforms and that any documentation, advertising materials, and other 
  275. Xmaterials related to such distribution and use acknowledge that the 
  276. Xsoftware was developed by Mark H. Colburn and sponsored by The 
  277. XUSENIX Association. 
  278. X.PP
  279. XTHE SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  280. XIMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  281. XWARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  282. X.SH AUTHOR
  283. XMark H. Colburn
  284. X.br
  285. XNAPS International
  286. X.br
  287. X117 Mackubin Street, Suite 1
  288. X.br
  289. XSt. Paul, MN 55102
  290. X.br
  291. Xmark@jhereg.MN.ORG
  292. X.sp 2
  293. XSponsored by
  294. X.B "The USENIX Association"
  295. Xfor public distribution.
  296. END_OF_cpio.1
  297. if test 6231 -ne `wc -c <cpio.1`; then
  298.     echo shar: \"cpio.1\" unpacked with wrong size!
  299. fi
  300. # end of overwriting check
  301. fi
  302. if test -f create.c -a "${1}" != "-c" ; then 
  303.   echo shar: Will not over-write existing file \"create.c\"
  304. else
  305. echo shar: Extracting \"create.c\" \(7830 characters\)
  306. sed "s/^X//" >create.c <<'END_OF_create.c'
  307. X/* $Source: /u/mark/src/pax/RCS/create.c,v $
  308. X *
  309. X * $Revision: 1.1 $
  310. X *
  311. X * create.c - Create a tape archive. 
  312. X *
  313. X * DESCRIPTION
  314. X *
  315. X *    These functions are used to create/write and archive from an set of
  316. X *    named files.
  317. X *
  318. X * AUTHOR
  319. X *
  320. X *         Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  321. X *
  322. X * Sponsored by The USENIX Association for public distribution. 
  323. X *
  324. X * Copyright (c) 1989 Mark H. Colburn.
  325. X * All rights reserved.
  326. X *
  327. X * Redistribution and use in source and binary forms are permitted
  328. X * provided that the above copyright notice is duplicated in all such 
  329. X * forms and that any documentation, advertising materials, and other 
  330. X * materials related to such distribution and use acknowledge that the 
  331. X * software was developed * by Mark H. Colburn and sponsored by The 
  332. X * USENIX Association. 
  333. X *
  334. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  335. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  336. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  337. X *
  338. X * $Log:    create.c,v $
  339. X * Revision 1.1  88/12/23  18:02:06  mark
  340. X * Initial revision
  341. X * 
  342. X */
  343. X
  344. X#ifndef lint
  345. Xstatic char *ident = "$Id: create.c,v 1.1 88/12/23 18:02:06 mark Rel $";
  346. Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  347. X#endif /* ! lint */
  348. X
  349. X
  350. X/* Headers */
  351. X
  352. X#include "pax.h"
  353. X
  354. X
  355. X/* Function Prototypes */
  356. X
  357. X#ifdef __STDC__
  358. X
  359. Xstatic void writetar(char *, Stat *);
  360. Xstatic void writecpio(char *, Stat *);
  361. Xstatic char tartype(int);
  362. X
  363. X#else /* !__STDC__ */
  364. X
  365. Xstatic void writetar();
  366. Xstatic void writecpio();
  367. Xstatic char tartype();
  368. X
  369. X#endif /* __STDC__ */
  370. X
  371. X
  372. X/* create_archive - create a tar archive.
  373. X *
  374. X * DESCRIPTION
  375. X *
  376. X *    Create_archive is used as an entry point to both create and append
  377. X *    archives.  Create archive goes through the files specified by the
  378. X *    user and writes each one to the archive if it can.  Create_archive
  379. X *    knows how to write both cpio and tar headers and the padding which
  380. X *    is needed for each type of archive.
  381. X *
  382. X * RETURNS
  383. X *
  384. X *    Always returns 0
  385. X */
  386. X
  387. X#ifdef __STDC__
  388. X
  389. Xint create_archive(void)
  390. X
  391. X#else
  392. X
  393. Xint create_archive()
  394. X
  395. X#endif
  396. X{
  397. X    char            name[PATH_MAX + 1];
  398. X    Stat            sb;
  399. X    int             fd;
  400. X
  401. X    while (name_next(name, &sb) != -1) {
  402. X    if ((fd = openi(name, &sb)) < 0) {
  403. X        /* FIXME: pax wants to exit here??? */
  404. X        continue;
  405. X    }
  406. X
  407. X    if (rplhead != NULL) {
  408. X        rpl_name(name);
  409. X        if (strlen(name) == 0) {
  410. X        continue;
  411. X        }
  412. X    }
  413. X    if (get_disposition("add", name) || get_newname(name, sizeof(name))) {
  414. X        /* skip file... */
  415. X        if (fd) {
  416. X        close(fd);
  417. X        }
  418. X        continue;
  419. X    } 
  420. X
  421. X    if (!f_link && sb.sb_nlink > 1) {
  422. X        if (islink(name, &sb)) {
  423. X        sb.sb_size = 0;
  424. X        }
  425. X        linkto(name, &sb);
  426. X    }
  427. X    if (ar_format == TAR) {
  428. X        writetar(name, &sb);
  429. X    } else {
  430. X        writecpio(name, &sb);
  431. X    }
  432. X    if (fd) {
  433. X        outdata(fd, name, sb.sb_size);
  434. X    }
  435. X    if (f_verbose) {
  436. X        print_entry(name, &sb);
  437. X    }
  438. X    }
  439. X
  440. X    write_eot();
  441. X    close_archive();
  442. X    return (0);
  443. X}
  444. X
  445. X
  446. X/* writetar - write a header block for a tar file
  447. X *
  448. X * DESCRIPTION
  449. X *
  450. X *     Make a header block for the file name whose stat info is in st.  
  451. X *    Return header pointer for success, NULL if the name is too long.
  452. X *
  453. X *     The tar header block is structured as follows:
  454. X *
  455. X *        FIELD NAME    OFFSET        SIZE
  456. X *          -------------|---------------|------
  457. X *        name          0        100
  458. X *        mode        100          8
  459. X *        uid        108          8
  460. X *        gid        116          8
  461. X *        size        124         12
  462. X *        mtime        136         12
  463. X *        chksum        148          8
  464. X *        typeflag    156          1
  465. X *        linkname    157        100
  466. X *        magic        257          6
  467. X *        version        263          2
  468. X *        uname        265         32
  469. X *        gname        297         32
  470. X *        devmajor    329          8
  471. X *        devminor    337          8
  472. X *        prefix        345        155
  473. X *
  474. X * PARAMETERS
  475. X *
  476. X *    char    *name    - name of file to create a header block for
  477. X *    Stat    *asb    - pointer to the stat structure for the named file
  478. X *
  479. X */
  480. X
  481. X#ifdef __STDC__
  482. X
  483. Xstatic void writetar(char *name, Stat *asb)
  484. X
  485. X#else
  486. X    
  487. Xstatic void writetar(name, asb)
  488. Xchar           *name;
  489. XStat           *asb;
  490. X
  491. X#endif
  492. X{
  493. X    char       *p;
  494. X    char           *prefix = NULL;
  495. X    int             i;
  496. X    int             sum;
  497. X    char            hdr[BLOCKSIZE];
  498. X    Link           *from;
  499. X
  500. X    memset(hdr, 0, BLOCKSIZE);
  501. X    if (strlen(name) > 255) {
  502. X    warn(name, "name too long");
  503. X    return;
  504. X    }
  505. X
  506. X    /* 
  507. X     * If the pathname is longer than TNAMLEN, but less than 255, then
  508. X     * we can split it up into the prefix and the filename.
  509. X     */
  510. X    if (strlen(name) > 100) {
  511. X    prefix = name;
  512. X    name += 155;
  513. X    while (name > prefix && *name != '/') {
  514. X        name--;
  515. X    }
  516. X
  517. X    /* no slash found....hmmm.... */
  518. X    if (name == prefix) {
  519. X        warn(prefix, "Name too long");
  520. X        return;
  521. X    }
  522. X    *name++ = '\0';
  523. X    }
  524. X
  525. X#ifdef S_IFLNK
  526. X    if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
  527. X    strcpy(&hdr[157], asb->sb_link);
  528. X    asb->sb_size = 0;
  529. X    }
  530. X#endif
  531. X    strcpy(hdr, name);
  532. X    sprintf(&hdr[100], "%06o \0", asb->sb_mode & ~S_IFMT);
  533. X    sprintf(&hdr[108], "%06o \0", asb->sb_uid);
  534. X    sprintf(&hdr[116], "%06o \0", asb->sb_gid);
  535. X    sprintf(&hdr[124], "%011lo ", (long) asb->sb_size);
  536. X    sprintf(&hdr[136], "%011lo ", (long) asb->sb_mtime);
  537. X    strncpy(&hdr[148], "        ", 8);
  538. X    hdr[156] = tartype(asb->sb_mode);
  539. X    if (asb->sb_nlink > 1 && (from = linkfrom(name, asb)) != NULL) {
  540. X    strcpy(&hdr[157], from->l_name);
  541. X    hdr[156] = LNKTYPE;
  542. X    }
  543. X    strcpy(&hdr[257], TMAGIC);
  544. X    strncpy(&hdr[263], TVERSION, 2);
  545. X    strcpy(&hdr[265], finduname((int) asb->sb_uid));
  546. X    strcpy(&hdr[297], findgname((int) asb->sb_gid));
  547. X    sprintf(&hdr[329], "%06o \0", major(asb->sb_rdev));
  548. X    sprintf(&hdr[337], "%06o \0", minor(asb->sb_rdev));
  549. X    if (prefix != NULL) {
  550. X    strncpy(&hdr[345], prefix, 155);
  551. X    }
  552. X
  553. X    /* Calculate the checksum */
  554. X
  555. X    sum = 0;
  556. X    p = hdr;
  557. X    for (i = 0; i < 500; i++) {
  558. X    sum += 0xFF & *p++;
  559. X    }
  560. X
  561. X    /* Fill in the checksum field. */
  562. X
  563. X    sprintf(&hdr[148], "%06o \0", sum);
  564. X
  565. X    outwrite(hdr, BLOCKSIZE);
  566. X}
  567. X
  568. X
  569. X/* tartype - return tar file type from file mode
  570. X *
  571. X * DESCRIPTION
  572. X *
  573. X *    tartype returns the character which represents the type of file
  574. X *    indicated by "mode". 
  575. X *
  576. X * PARAMETERS
  577. X *
  578. X *    int    mode    - file mode from a stat block
  579. X *
  580. X * RETURNS
  581. X *
  582. X *    The character which represents the particular file type in the 
  583. X *    ustar standard headers.
  584. X */
  585. X
  586. X#ifdef __STDC__
  587. X
  588. Xstatic char tartype(int mode)
  589. X
  590. X#else
  591. X    
  592. Xstatic char tartype(mode)
  593. Xint        mode;
  594. X
  595. X#endif
  596. X{
  597. X    switch (mode & S_IFMT) {
  598. X
  599. X#ifdef S_IFCTG
  600. X    case S_IFCTG:
  601. X    return(CONTTYPE);
  602. X#endif
  603. X
  604. X    case S_IFDIR:
  605. X    return (DIRTYPE);
  606. X
  607. X#ifdef S_IFLNK
  608. X    case S_IFLNK:
  609. X    return (SYMTYPE);
  610. X#endif
  611. X
  612. X#ifdef S_IFFIFO
  613. X    case S_IFIFO:
  614. X    return (FIFOTYPE);
  615. X#endif
  616. X
  617. X#ifdef S_IFCHR
  618. X    case S_IFCHR:
  619. X    return (CHRTYPE);
  620. X#endif
  621. X
  622. X#ifdef S_IFBLK
  623. X    case S_IFBLK:
  624. X    return (BLKTYPE);
  625. X#endif
  626. X
  627. X    default:
  628. X    return (REGTYPE);
  629. X    }
  630. X}
  631. X
  632. X
  633. X/* writecpio - write a cpio archive header
  634. X *
  635. X * DESCRIPTION
  636. X *
  637. X *    Writes a new CPIO style archive header for the file specified.
  638. X *
  639. X * PARAMETERS
  640. X *
  641. X *    char    *name    - name of file to create a header block for
  642. X *    Stat    *asb    - pointer to the stat structure for the named file
  643. X */
  644. X
  645. X#ifdef __STDC__
  646. X
  647. Xstatic void writecpio(char *name, Stat *asb)
  648. X
  649. X#else
  650. X    
  651. Xstatic void writecpio(name, asb)
  652. Xchar           *name;
  653. XStat           *asb;
  654. X
  655. X#endif
  656. X{
  657. X    uint            namelen;
  658. X    char            header[M_STRLEN + H_STRLEN + 1];
  659. X
  660. X    namelen = (uint) strlen(name) + 1;
  661. X    strcpy(header, M_ASCII);
  662. X    sprintf(header + M_STRLEN, "%06o%06o%06o%06o%06o",
  663. X        USH(asb->sb_dev), USH(asb->sb_ino), USH(asb->sb_mode), 
  664. X        USH(asb->sb_uid), USH(asb->sb_gid));
  665. X    sprintf(header + M_STRLEN + 30, "%06o%06o%011lo%06o%011lo",
  666. X        USH(asb->sb_nlink), USH(asb->sb_rdev),
  667. X        f_modification_time ? asb->sb_mtime : time((time_t *) 0),
  668. X        namelen, asb->sb_size);
  669. X    outwrite(header, M_STRLEN + H_STRLEN);
  670. X    outwrite(name, namelen);
  671. X#ifdef    S_IFLNK
  672. X    if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
  673. X    outwrite(asb->sb_link, (uint) asb->sb_size);
  674. X    }
  675. X#endif    /* S_IFLNK */
  676. X}
  677. END_OF_create.c
  678. if test 7830 -ne `wc -c <create.c`; then
  679.     echo shar: \"create.c\" unpacked with wrong size!
  680. fi
  681. # end of overwriting check
  682. fi
  683. if test -f func.h -a "${1}" != "-c" ; then 
  684.   echo shar: Will not over-write existing file \"func.h\"
  685. else
  686. echo shar: Extracting \"func.h\" \(5047 characters\)
  687. sed "s/^X//" >func.h <<'END_OF_func.h'
  688. X/* $Source: /u/mark/src/pax/RCS/func.h,v $
  689. X *
  690. X * $Revision: 1.1 $
  691. X *
  692. X * func.h - function type and argument declarations
  693. X *
  694. X * DESCRIPTION
  695. X *
  696. X *    This file contains function delcarations in both ANSI style
  697. X *    (function prototypes) and traditional style. 
  698. X *
  699. X * AUTHOR
  700. X *
  701. X *     Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  702. X *
  703. X * Sponsored by The USENIX Association for public distribution. 
  704. X *
  705. X * Copyright (c) 1989 Mark H. Colburn.
  706. X * All rights reserved.
  707. X *
  708. X * Redistribution and use in source and binary forms are permitted
  709. X * provided that the above copyright notice and this paragraph are
  710. X * duplicated in all such forms and that any documentation,
  711. X * advertising materials, and other materials related to such
  712. X * distribution and use acknowledge that the software was developed
  713. X * by Mark H. Colburn and sponsored by The USENIX Association. 
  714. X *
  715. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  716. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  717. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  718. X */
  719. X
  720. X#ifndef _PAX_FUNC_H
  721. X#define _PAX_FUNC_H
  722. X
  723. X/* Function Prototypes */
  724. X
  725. X#ifdef __STDC__
  726. X
  727. Xextern Link               *linkfrom(char *, Stat *);
  728. Xextern Link               *linkto(char *, Stat *);
  729. Xextern char               *mem_get(uint);
  730. Xextern char               *mem_str(char *);
  731. Xextern char               *syserr(void);
  732. Xextern int          ar_read(void);
  733. Xextern int          buf_read(char *, uint);
  734. Xextern int          buf_skip(OFFSET);
  735. Xextern int          create_archive(void);
  736. Xextern int          dirneed(char *);
  737. Xextern int          read_archive(void);
  738. Xextern int          inentry(char *, Stat *);
  739. Xextern int          lineget(FILE *, char *);
  740. Xextern int          name_match(char *);
  741. Xextern int          name_next(char *, Stat *);
  742. Xextern int          nameopt(char *);
  743. Xextern int          open_archive(int);
  744. Xextern int          open_tty(void);
  745. Xextern int          openi(char *, Stat *);
  746. Xextern int          openo(char *, Stat *, Link *, int);
  747. Xextern int          pass(char *);
  748. Xextern int          passitem(char *, Stat *, int, char *);
  749. Xextern int          read_header(char *, Stat *);
  750. Xextern int          wildmat(char *, char *);
  751. Xextern void         buf_allocate(OFFSET);
  752. Xextern void         close_archive(void);
  753. Xextern void         fatal(char *);
  754. Xextern void         name_gather(void);
  755. Xextern void         name_init(int, char **);
  756. Xextern void         names_notfound(void);
  757. Xextern void         next(int);
  758. Xextern int          nextask(char *, char *, int);
  759. Xextern void         outdata(int, char *, OFFSET);
  760. Xextern void         outwrite(char *, uint);
  761. Xextern void         passdata(char *, int, char *, int);
  762. Xextern void         print_entry(char *, Stat *);
  763. Xextern void         warn();
  764. Xextern void        warnarch(char *, OFFSET);
  765. Xextern void         write_eot(void);
  766. Xextern void        get_archive_type(void);
  767. Xextern struct group    *getgrgid();
  768. Xextern struct group    *getgrnam();
  769. Xextern struct passwd   *getpwuid();
  770. Xextern char               *getenv(char *);
  771. Xextern SIG_T             (*signal())();
  772. Xextern Link            *islink(char *, Stat *);
  773. Xextern char            *finduname(int);
  774. Xextern char            *findgname(int);
  775. Xextern int        findgid(char *gname);
  776. X
  777. X#else /* !__STDC__ */
  778. X
  779. Xextern Link               *linkfrom();
  780. Xextern Link               *linkto();
  781. Xextern char               *mem_get();
  782. Xextern char               *mem_str();
  783. Xextern char               *syserr();
  784. Xextern int          ar_read();
  785. Xextern int          buf_read();
  786. Xextern int          buf_skip();
  787. Xextern int          create_archive();
  788. Xextern int          dirneed();
  789. Xextern int          read_archive();
  790. Xextern int          inentry();
  791. Xextern int          lineget();
  792. Xextern int          name_match();
  793. Xextern int          name_next();
  794. Xextern int          nameopt();
  795. Xextern int          open_archive();
  796. Xextern int          open_tty();
  797. Xextern int          openi();
  798. Xextern int          openo();
  799. Xextern int          pass();
  800. Xextern int          passitem();
  801. Xextern int              read_header();
  802. Xextern int          wildmat();
  803. Xextern void         buf_allocate();
  804. Xextern void         close_archive();
  805. Xextern void         fatal();
  806. Xextern void         name_gather();
  807. Xextern void         name_init();
  808. Xextern void         names_notfound();
  809. Xextern void         next();
  810. Xextern int          nextask();
  811. Xextern void         outdata();
  812. Xextern void         outwrite();
  813. Xextern void         passdata();
  814. Xextern void         print_entry();
  815. Xextern void         warn();
  816. Xextern void         warnarch();
  817. Xextern void         write_eot();
  818. Xextern void        get_archive_type();
  819. Xextern char               *getenv();
  820. Xextern char               *malloc();
  821. Xextern char               *strcat();
  822. Xextern char               *strcpy();
  823. Xextern char               *strncpy();
  824. Xextern SIG_T             (*signal())();
  825. Xextern OFFSET       lseek();
  826. Xextern struct group    *getgrgid();
  827. Xextern struct group    *getgrnam();
  828. Xextern struct passwd   *getpwuid();
  829. Xextern struct tm       *localtime();
  830. Xextern time_t              time();
  831. Xextern uint                sleep();
  832. Xextern void                _exit();
  833. Xextern void                exit();
  834. Xextern void                free();
  835. Xextern Link            *islink();
  836. Xextern char            *finduname();
  837. Xextern char            *findgname();
  838. Xextern int        findgid();
  839. X
  840. X#endif /* __STDC__ */
  841. X#endif /* _PAX_FUNC_H */
  842. END_OF_func.h
  843. if test 5047 -ne `wc -c <func.h`; then
  844.     echo shar: \"func.h\" unpacked with wrong size!
  845. fi
  846. # end of overwriting check
  847. fi
  848. if test -f link.c -a "${1}" != "-c" ; then 
  849.   echo shar: Will not over-write existing file \"link.c\"
  850. else
  851. echo shar: Extracting \"link.c\" \(7575 characters\)
  852. sed "s/^X//" >link.c <<'END_OF_link.c'
  853. X/* $Source: /u/mark/src/pax/RCS/link.c,v $
  854. X *
  855. X * $Revision: 1.1 $
  856. X *
  857. X * link.c - functions for handling multiple file links 
  858. X *
  859. X * DESCRIPTION
  860. X *
  861. X *    These function manage the link chains which are used to keep track
  862. X *    of outstanding links during archive reading and writing.
  863. X *
  864. X * AUTHOR
  865. X *
  866. X *    Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  867. X *
  868. X * Sponsored by The USENIX Association for public distribution. 
  869. X *
  870. X * Copyright (c) 1989 Mark H. Colburn.
  871. X * All rights reserved.
  872. X *
  873. X * Redistribution and use in source and binary forms are permitted
  874. X * provided that the above copyright notice is duplicated in all such 
  875. X * forms and that any documentation, advertising materials, and other 
  876. X * materials related to such distribution and use acknowledge that the 
  877. X * software was developed * by Mark H. Colburn and sponsored by The 
  878. X * USENIX Association. 
  879. X *
  880. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  881. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  882. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  883. X *
  884. X * $Log:    link.c,v $
  885. X * Revision 1.1  88/12/23  18:02:12  mark
  886. X * Initial revision
  887. X * 
  888. X */
  889. X
  890. X#ifndef lint
  891. Xstatic char *ident = "$Id: link.c,v 1.1 88/12/23 18:02:12 mark Rel $";
  892. Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  893. X#endif /* ! lint */
  894. X
  895. X
  896. X/* Headers */
  897. X
  898. X#include "pax.h"
  899. X
  900. X
  901. X/* Defines */
  902. X
  903. X/*
  904. X * Address link information base. 
  905. X */
  906. X#define    LINKHASH(ino)    (linkbase + (ino) % NEL(linkbase))
  907. X
  908. X/*
  909. X * Number of array elements. 
  910. X */
  911. X#define    NEL(a)        (sizeof(a) / sizeof(*(a)))
  912. X
  913. X
  914. X
  915. X/* Internal Identifiers */
  916. X
  917. Xstatic Link    *linkbase[256];    /* Unresolved link information */
  918. X
  919. X
  920. X/* linkfrom - find a file to link from 
  921. X *
  922. X * DESCRIPTION
  923. X *
  924. X *    Linkfrom searches the link chain to see if there is a file in the
  925. X *    link chain which has the same inode number as the file specified
  926. X *    by the stat block pointed at by asb.  If a file is found, the
  927. X *    name is returned to the caller, otherwise a NULL is returned.
  928. X *
  929. X * PARAMETERS
  930. X *
  931. X *    char    *name   - name of the file which we are attempting
  932. X *                        to find a link for
  933. X *    Stat    *asb    - stat structure of file to find a link to
  934. X *
  935. X * RETURNS
  936. X *
  937. X *     Returns a pointer to a link structure, or NULL if unsuccessful. 
  938. X *
  939. X */
  940. X
  941. X#ifdef __STDC__
  942. X
  943. XLink *linkfrom(char *name, Stat *asb)
  944. X
  945. X#else
  946. X    
  947. XLink *linkfrom(name, asb)
  948. Xchar           *name;
  949. XStat           *asb;
  950. X
  951. X#endif
  952. X{
  953. X    Link           *linkp;
  954. X    Link           *linknext;
  955. X    Path           *path;
  956. X    Path           *pathnext;
  957. X    Link          **abase;
  958. X
  959. X    for (linkp = *(abase = LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
  960. X    if (linkp->l_nlink == 0) {
  961. X        if (linkp->l_name) {
  962. X        free((char *) linkp->l_name);
  963. X        }
  964. X        if (linknext = linkp->l_forw) {
  965. X        linknext->l_back = linkp->l_back;
  966. X        }
  967. X        if (linkp->l_back) {
  968. X        linkp->l_back->l_forw = linkp->l_forw;
  969. X        }
  970. X        free((char *) linkp);
  971. X        *abase = (Link *) NULL;
  972. X    } else if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
  973. X        /* 
  974. X         * check to see if a file with the name "name" exists in the 
  975. X         * chain of files which we have for this particular link
  976. X         */
  977. X        for (path = linkp->l_path; path; path = pathnext) {
  978. X        if (strcmp(path->p_name, name) == 0) {
  979. X            --linkp->l_nlink;
  980. X            if (path->p_name) {
  981. X            free(path->p_name);
  982. X            }
  983. X            if (pathnext = path->p_forw) {
  984. X            pathnext->p_back = path->p_back;
  985. X            }
  986. X            if (path->p_back) {
  987. X            path->p_back->p_forw = pathnext;
  988. X            }
  989. X            if (linkp->l_path == path) {
  990. X            linkp->l_path = pathnext;
  991. X            }
  992. X            free(path);
  993. X            return (linkp);
  994. X        }
  995. X        pathnext = path->p_forw;
  996. X        }
  997. X        return((Link *)NULL);
  998. X    } else {
  999. X        linknext = linkp->l_forw;
  1000. X    }
  1001. X    }
  1002. X    return ((Link *)NULL);
  1003. X}
  1004. X
  1005. X
  1006. X
  1007. X/* islink - determine whether a given file really a link
  1008. X *
  1009. X * DESCRIPTION
  1010. X *
  1011. X *    Islink searches the link chain to see if there is a file in the
  1012. X *    link chain which has the same inode number as the file specified
  1013. X *    by the stat block pointed at by asb.  If a file is found, a
  1014. X *    non-zero value is returned to the caller, otherwise a 0 is
  1015. X *    returned.
  1016. X *
  1017. X * PARAMETERS
  1018. X *
  1019. X *    char    *name   - name of file to check to see if it is link.
  1020. X *    Stat    *asb    - stat structure of file to find a link to
  1021. X *
  1022. X * RETURNS
  1023. X *
  1024. X *     Returns a pointer to a link structure, or NULL if unsuccessful. 
  1025. X *
  1026. X */
  1027. X
  1028. X#ifdef __STDC__
  1029. X
  1030. XLink *islink(char *name, Stat *asb)
  1031. X
  1032. X#else
  1033. X    
  1034. XLink *islink(name, asb)
  1035. Xchar           *name;
  1036. XStat           *asb;
  1037. X
  1038. X#endif
  1039. X{
  1040. X    Link           *linkp;
  1041. X    Link           *linknext;
  1042. X
  1043. X    for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
  1044. X    if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
  1045. X        if (strcmp(name, linkp->l_name) == 0) {
  1046. X        return ((Link *) NULL);
  1047. X        } 
  1048. X        return (linkp);
  1049. X    } else {
  1050. X        linknext = linkp->l_forw;
  1051. X    }
  1052. X    }
  1053. X    return ((Link *)NULL);
  1054. X}
  1055. X
  1056. X
  1057. X/* linkto  - remember a file with outstanding links 
  1058. X *
  1059. X * DESCRIPTION
  1060. X *
  1061. X *    Linkto adds the specified file to the link chain.  Any subsequent
  1062. X *    calls to linkfrom which have the same inode will match the file
  1063. X *    just entered.  If not enough space is available to make the link
  1064. X *    then the item is not added to the link chain, and a NULL is
  1065. X *    returned to the calling function.
  1066. X *
  1067. X * PARAMETERS
  1068. X *
  1069. X *    char    *name    - name of file to remember
  1070. X *    Stat    *asb    - pointer to stat structure of file to remember
  1071. X *
  1072. X * RETURNS
  1073. X *
  1074. X *     Returns a pointer to the associated link structure, or NULL when 
  1075. X *    linking is not possible. 
  1076. X *
  1077. X */
  1078. X
  1079. X#ifdef __STDC__
  1080. X
  1081. XLink *linkto(char *name, Stat *asb)
  1082. X
  1083. X#else
  1084. X    
  1085. XLink *linkto(name, asb)
  1086. Xchar           *name;
  1087. XStat           *asb;
  1088. X
  1089. X#endif
  1090. X{
  1091. X    Link           *linkp;
  1092. X    Link           *linknext;
  1093. X    Path           *path;
  1094. X    Link          **abase;
  1095. X
  1096. X    for (linkp = *(LINKHASH(asb->sb_ino)); linkp; linkp = linknext) {
  1097. X    if (linkp->l_ino == asb->sb_ino && linkp->l_dev == asb->sb_dev) {
  1098. X        if ((path = (Path *) mem_get(sizeof(Path))) == (Path *) NULL || 
  1099. X        (path->p_name = mem_str(name)) == (char *) NULL) {
  1100. X        return((Link *) NULL);
  1101. X        }
  1102. X        if (path->p_forw = linkp->l_path) {
  1103. X        if (linkp->l_path->p_forw) {
  1104. X            linkp->l_path->p_forw->p_back = path;
  1105. X        }
  1106. X        } else {
  1107. X        linkp->l_path = path;
  1108. X        }
  1109. X        path->p_back = (Path *) NULL;
  1110. X        return(linkp);
  1111. X    } else {
  1112. X        linknext = linkp->l_forw;
  1113. X    }
  1114. X    }
  1115. X    /*
  1116. X     * This is a brand new link, for which there is no other information
  1117. X     */
  1118. X
  1119. X    if ((asb->sb_mode & S_IFMT) == S_IFDIR
  1120. X    || (linkp = (Link *) mem_get(sizeof(Link))) == NULL
  1121. X    || (linkp->l_name = mem_str(name)) == NULL) {
  1122. X    return ((Link *) NULL);
  1123. X    }
  1124. X    linkp->l_dev = asb->sb_dev;
  1125. X    linkp->l_ino = asb->sb_ino;
  1126. X    linkp->l_nlink = asb->sb_nlink - 1;
  1127. X    linkp->l_size = asb->sb_size;
  1128. X    linkp->l_path = (Path *) NULL;
  1129. X    if (linkp->l_forw = *(abase = LINKHASH(asb->sb_ino))) {
  1130. X    linkp->l_forw->l_back = linkp;
  1131. X    } else {
  1132. X    *abase = linkp;
  1133. X    }
  1134. X    linkp->l_back = NULL;
  1135. X    return (linkp);
  1136. X}
  1137. X
  1138. X
  1139. X/* linkleft - complain about files with unseen links 
  1140. X *
  1141. X * DESCRIPTION
  1142. X *
  1143. X *    Linksleft scans through the link chain to see if there were any
  1144. X *    files which have outstanding links that were not processed by the
  1145. X *    archive.  For each file in the link chain for which there was not
  1146. X *    a file,  and error message is printed.
  1147. X */
  1148. X
  1149. X#ifdef __STDC__
  1150. X
  1151. Xvoid linkleft(void)
  1152. X
  1153. X#else
  1154. X    
  1155. Xvoid linkleft()
  1156. X
  1157. X#endif
  1158. X{
  1159. X    Link           *lp;
  1160. X    Link          **base;
  1161. X
  1162. X    for (base = linkbase; base < linkbase + NEL(linkbase); ++base) {
  1163. X    for (lp = *base; lp; lp = lp->l_forw) {
  1164. X        if (lp->l_nlink) {
  1165. X        warn(lp->l_path->p_name, "Unseen link(s)");
  1166. X        }
  1167. X    }
  1168. X    }
  1169. X}
  1170. END_OF_link.c
  1171. if test 7575 -ne `wc -c <link.c`; then
  1172.     echo shar: \"link.c\" unpacked with wrong size!
  1173. fi
  1174. # end of overwriting check
  1175. fi
  1176. if test -f names.c -a "${1}" != "-c" ; then 
  1177.   echo shar: Will not over-write existing file \"names.c\"
  1178. else
  1179. echo shar: Extracting \"names.c\" \(5005 characters\)
  1180. sed "s/^X//" >names.c <<'END_OF_names.c'
  1181. X/* $Source: /u/mark/src/pax/RCS/names.c,v $
  1182. X *
  1183. X * $Revision: 1.1 $
  1184. X *
  1185. X * names.c - Look up user and/or group names. 
  1186. X *
  1187. X * DESCRIPTION
  1188. X *
  1189. X *    These functions support UID and GID name lookup.  The results are
  1190. X *    cached to improve performance.
  1191. X *
  1192. X * AUTHOR
  1193. X *
  1194. X *    Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  1195. X *
  1196. X * Sponsored by The USENIX Association for public distribution. 
  1197. X *
  1198. X * Copyright (c) 1989 Mark H. Colburn.
  1199. X * All rights reserved.
  1200. X *
  1201. X * Redistribution and use in source and binary forms are permitted
  1202. X * provided that the above copyright notice is duplicated in all such 
  1203. X * forms and that any documentation, advertising materials, and other 
  1204. X * materials related to such distribution and use acknowledge that the 
  1205. X * software was developed * by Mark H. Colburn and sponsored by The 
  1206. X * USENIX Association. 
  1207. X *
  1208. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1209. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1210. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1211. X *
  1212. X * $Log:    names.c,v $
  1213. X * Revision 1.1  88/12/23  18:02:19  mark
  1214. X * Initial revision
  1215. X * 
  1216. X */
  1217. X
  1218. X#ifndef lint
  1219. Xstatic char *ident = "$Id: names.c,v 1.1 88/12/23 18:02:19 mark Rel $";
  1220. Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  1221. X#endif /* ! lint */
  1222. X
  1223. X
  1224. X/* Headers */
  1225. X
  1226. X#include "pax.h"
  1227. X
  1228. X
  1229. X/* Defines */
  1230. X
  1231. X#define myuid    ( my_uid < 0? (my_uid = getuid()): my_uid )
  1232. X#define    mygid    ( my_gid < 0? (my_gid = getgid()): my_gid )
  1233. X
  1234. X
  1235. X/* Internal Identifiers */
  1236. X
  1237. Xstatic int      saveuid = -993;
  1238. Xstatic char     saveuname[TUNMLEN];
  1239. Xstatic int      my_uid = -993;
  1240. X
  1241. Xstatic int      savegid = -993;
  1242. Xstatic char     savegname[TGNMLEN];
  1243. Xstatic int      my_gid = -993;
  1244. X
  1245. X
  1246. X/* finduname - find a user or group name from a uid or gid
  1247. X *
  1248. X * DESCRIPTION
  1249. X *
  1250. X *     Look up a user name from a uid/gid, maintaining a cache. 
  1251. X *
  1252. X * PARAMETERS
  1253. X *
  1254. X *    char    uname[]        - name (to be returned to user)
  1255. X *    int    uuid        - id of name to find
  1256. X *
  1257. X *
  1258. X * RETURNS
  1259. X *
  1260. X *    Returns a name which is associated with the user id given.  If there
  1261. X *    is not name which corresponds to the user-id given, then a pointer
  1262. X *    to a string of zero length is returned.
  1263. X *    
  1264. X * FIXME
  1265. X *
  1266. X *     1. for now it's a one-entry cache. 
  1267. X *    2. The "-993" is to reduce the chance of a hit on the first lookup. 
  1268. X */
  1269. X
  1270. X#ifdef __STDC__
  1271. X
  1272. Xchar *finduname(int uuid)
  1273. X
  1274. X#else
  1275. X    
  1276. Xchar *finduname(uuid)
  1277. Xint             uuid;
  1278. X
  1279. X#endif
  1280. X{
  1281. X    struct passwd  *pw;
  1282. X
  1283. X    if (uuid != saveuid) {
  1284. X    saveuid = uuid;
  1285. X    saveuname[0] = '\0';
  1286. X    pw = getpwuid(uuid);
  1287. X    if (pw) {
  1288. X        strncpy(saveuname, pw->pw_name, TUNMLEN);
  1289. X    }
  1290. X    }
  1291. X    return(saveuname);
  1292. X}
  1293. X
  1294. X
  1295. X/* finduid - get the uid for a given user name
  1296. X *
  1297. X * DESCRIPTION
  1298. X *
  1299. X *    This does just the opposit of finduname.  Given a user name it
  1300. X *    finds the corresponding UID for that name.
  1301. X *
  1302. X * PARAMETERS
  1303. X *
  1304. X *    char    uname[]        - username to find a UID for
  1305. X *
  1306. X * RETURNS
  1307. X *
  1308. X *    The UID which corresponds to the uname given, if any.  If no UID
  1309. X *    could be found, then the UID which corrsponds the user running the
  1310. X *    program is returned.
  1311. X *
  1312. X */
  1313. X
  1314. X#ifdef __STDC__
  1315. X
  1316. Xint finduid(char *uname)
  1317. X
  1318. X#else
  1319. X    
  1320. Xint finduid(uname)
  1321. Xchar            *uname;
  1322. X
  1323. X#endif
  1324. X{
  1325. X    struct passwd  *pw;
  1326. X    extern struct passwd *getpwnam();
  1327. X
  1328. X    if (uname[0] != saveuname[0]/* Quick test w/o proc call */
  1329. X    ||0 != strncmp(uname, saveuname, TUNMLEN)) {
  1330. X    strncpy(saveuname, uname, TUNMLEN);
  1331. X    pw = getpwnam(uname);
  1332. X    if (pw) {
  1333. X        saveuid = pw->pw_uid;
  1334. X    } else {
  1335. X        saveuid = myuid;
  1336. X    }
  1337. X    }
  1338. X    return (saveuid);
  1339. X}
  1340. X
  1341. X
  1342. X/* findgname - look up a group name from a gid
  1343. X *
  1344. X * DESCRIPTION
  1345. X *
  1346. X *     Look up a group name from a gid, maintaining a cache.
  1347. X *    
  1348. X *
  1349. X * PARAMETERS
  1350. X *
  1351. X *    int    ggid        - goupid of group to find
  1352. X *
  1353. X * RETURNS
  1354. X *
  1355. X *    A string which is associated with the group ID given.  If no name
  1356. X *    can be found, a string of zero length is returned.
  1357. X */
  1358. X
  1359. X#ifdef __STDC__
  1360. X
  1361. Xchar *findgname(int ggid)
  1362. X
  1363. X#else
  1364. X    
  1365. Xchar *findgname(ggid)
  1366. Xint             ggid;
  1367. X
  1368. X#endif
  1369. X{
  1370. X    struct group   *gr;
  1371. X
  1372. X    if (ggid != savegid) {
  1373. X    savegid = ggid;
  1374. X    savegname[0] = '\0';
  1375. X    setgrent();
  1376. X    gr = getgrgid(ggid);
  1377. X    if (gr) {
  1378. X        strncpy(savegname, gr->gr_name, TGNMLEN);
  1379. X    }
  1380. X    }
  1381. X    return(savegname);
  1382. X}
  1383. X
  1384. X
  1385. X
  1386. X/* findgid - get the gid for a given group name
  1387. X *
  1388. X * DESCRIPTION
  1389. X *
  1390. X *    This does just the opposit of finduname.  Given a group name it
  1391. X *    finds the corresponding GID for that name.
  1392. X *
  1393. X * PARAMETERS
  1394. X *
  1395. X *    char    uname[]        - groupname to find a GID for
  1396. X *
  1397. X * RETURNS
  1398. X *
  1399. X *    The GID which corresponds to the uname given, if any.  If no GID
  1400. X *    could be found, then the GID which corrsponds the group running the
  1401. X *    program is returned.
  1402. X *
  1403. X */
  1404. X
  1405. X#ifdef __STDC__
  1406. X
  1407. Xint findgid(char *gname)
  1408. X
  1409. X#else
  1410. X    
  1411. Xint findgid(gname)
  1412. Xchar           *gname;
  1413. X
  1414. X#endif
  1415. X{
  1416. X    struct group   *gr;
  1417. X
  1418. X    /* Quick test w/o proc call */
  1419. X    if (gname[0] != savegname[0] || strncmp(gname, savegname, TUNMLEN) != 0) {
  1420. X    strncpy(savegname, gname, TUNMLEN);
  1421. X    gr = getgrnam(gname);
  1422. X    if (gr) {
  1423. X        savegid = gr->gr_gid;
  1424. X    } else {
  1425. X        savegid = mygid;
  1426. X    }
  1427. X    }
  1428. X    return (savegid);
  1429. X}
  1430. END_OF_names.c
  1431. if test 5005 -ne `wc -c <names.c`; then
  1432.     echo shar: \"names.c\" unpacked with wrong size!
  1433. fi
  1434. # end of overwriting check
  1435. fi
  1436. if test -f replace.c -a "${1}" != "-c" ; then 
  1437.   echo shar: Will not over-write existing file \"replace.c\"
  1438. else
  1439. echo shar: Extracting \"replace.c\" \(6493 characters\)
  1440. sed "s/^X//" >replace.c <<'END_OF_replace.c'
  1441. X/* $Source: /u/mark/src/pax/RCS/replace.c,v $
  1442. X *
  1443. X * $Revision: 1.1 $
  1444. X *
  1445. X * replace.c - regular expression pattern replacement functions
  1446. X *
  1447. X * DESCRIPTION
  1448. X *
  1449. X *    These routines provide for regular expression file name replacement
  1450. X *    as required by pax.
  1451. X *
  1452. X * AUTHORS
  1453. X *
  1454. X *    Mark H. Colburn, NAPS International
  1455. X *
  1456. X * Sponsored by The USENIX Association for public distribution. 
  1457. X *
  1458. X * Copyright (c) 1989 Mark H. Colburn.
  1459. X * All rights reserved.
  1460. X *
  1461. X * Redistribution and use in source and binary forms are permitted
  1462. X * provided that the above copyright notice is duplicated in all such 
  1463. X * forms and that any documentation, advertising materials, and other 
  1464. X * materials related to such distribution and use acknowledge that the 
  1465. X * software was developed * by Mark H. Colburn and sponsored by The 
  1466. X * USENIX Association. 
  1467. X *
  1468. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1469. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1470. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1471. X *
  1472. X * $Log:    replace.c,v $
  1473. X * Revision 1.1  88/12/23  18:02:36  mark
  1474. X * Initial revision
  1475. X * 
  1476. X */
  1477. X
  1478. X#ifndef lint
  1479. Xstatic char *ident = "$Id: replace.c,v 1.1 88/12/23 18:02:36 mark Rel $";
  1480. Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  1481. X#endif /* not lint */
  1482. X
  1483. X/* Headers */
  1484. X
  1485. X#include "pax.h"
  1486. X
  1487. X
  1488. X/* add_replstr - add a replacement string to the replacement string list
  1489. X *
  1490. X * DESCRIPTION
  1491. X *
  1492. X *    Add_replstr adds a replacement string to the replacement string
  1493. X *    list which is applied each time a file is about to be processed.
  1494. X *
  1495. X * PARAMETERS
  1496. X *
  1497. X *    char    *pattern    - A regular expression which is to be parsed
  1498. X */
  1499. X
  1500. X#ifdef __STDC__
  1501. X
  1502. Xvoid add_replstr(char *pattern)
  1503. X
  1504. X#else
  1505. X
  1506. Xvoid add_replstr(pattern)
  1507. Xchar           *pattern;
  1508. X
  1509. X#endif
  1510. X{
  1511. X    char           *p;
  1512. X    char            sep;
  1513. X    Replstr        *rptr;
  1514. X    int             len;
  1515. X
  1516. X    if ((len = strlen(pattern)) < 4) {
  1517. X    warn("Replacement string not added",
  1518. X         "Malformed substitution syntax");
  1519. X    return;
  1520. X    }
  1521. X    if ((rptr = (Replstr *) malloc(sizeof(Replstr))) == NULL) {
  1522. X    warn("Replacement string not added", "No space");
  1523. X    return;
  1524. X    }
  1525. X
  1526. X    /* First character is the delimeter... */
  1527. X    sep = *pattern;
  1528. X
  1529. X    /* Get trailing g and/or p */
  1530. X    p = pattern + len - 1;
  1531. X    while (*p != sep) {
  1532. X    if (*p == 'g') {
  1533. X            rptr->global = 1;
  1534. X    } else if (*p == 'p') {
  1535. X        rptr->print = 1;
  1536. X    } else {
  1537. X        warn(p, "Invalid RE modifier");
  1538. X    }
  1539. X    p--;
  1540. X    }
  1541. X
  1542. X    if (*p != sep) {
  1543. X    warn("Replacement string not added", "Bad delimeters");
  1544. X    free(rptr);
  1545. X    return;
  1546. X    }
  1547. X    /* strip off leading and trailing delimeter */
  1548. X    *p = '\0';
  1549. X    pattern++;
  1550. X
  1551. X    /* find the separating '/' in the pattern */
  1552. X    p = pattern;
  1553. X    while (*p) {
  1554. X    if (*p == sep) {
  1555. X        break;
  1556. X    }
  1557. X    if (*p == '\\' && *(p + 1) != '\0') {
  1558. X        p++;
  1559. X    }
  1560. X    p++;
  1561. X    }
  1562. X    if (*p != sep) {
  1563. X    warn("Replacement string not added", "Bad delimeters");
  1564. X    free(rptr);
  1565. X    return;
  1566. X    }
  1567. X    *p++ = '\0';
  1568. X
  1569. X    /*
  1570. X     * Now pattern points to 'old' and p points to 'new' and both are '\0'
  1571. X     * terminated 
  1572. X     */
  1573. X    if ((rptr->comp = regcomp(pattern)) == NULL) {
  1574. X    warn("Replacement string not added", "Invalid RE");
  1575. X    free(rptr);
  1576. X    return;
  1577. X    }
  1578. X    rptr->replace = p;
  1579. X    rptr->next = NULL;
  1580. X    if (rplhead == NULL) {
  1581. X    rplhead = rptr;
  1582. X    rpltail = rptr;
  1583. X    } else {
  1584. X    rpltail->next = rptr;
  1585. X    rpltail = rptr;
  1586. X    }
  1587. X}
  1588. X
  1589. X
  1590. X
  1591. X/* rpl_name - possibly replace a name with a regular expression
  1592. X *
  1593. X * DESCRIPTION
  1594. X *
  1595. X *    The string name is searched for in the list of regular expression
  1596. X *    substituions.  If the string matches any of the regular expressions
  1597. X *    then the string is modified as specified by the user.
  1598. X *
  1599. X * PARAMETERS
  1600. X *
  1601. X *    char    *name    - name to search for and possibly modify
  1602. X */
  1603. X
  1604. X#ifdef __STDC__
  1605. X
  1606. Xvoid rpl_name(char *name)
  1607. X
  1608. X#else
  1609. X
  1610. Xvoid rpl_name(name)
  1611. Xchar           *name;
  1612. X
  1613. X#endif
  1614. X{
  1615. X    int             found = 0;
  1616. X    int             ret;
  1617. X    Replstr        *rptr;
  1618. X    char            buff[PATH_MAX + 1];
  1619. X    char            buff1[PATH_MAX + 1];
  1620. X    char            buff2[PATH_MAX + 1];
  1621. X    char           *p;
  1622. X    char           *b;
  1623. X
  1624. X    strcpy(buff, name);
  1625. X    for (rptr = rplhead; !found && rptr != NULL; rptr = rptr->next) {
  1626. X    do {
  1627. X        if ((ret = regexec(rptr->comp, buff)) != 0) {
  1628. X        p = buff;
  1629. X        b = buff1;
  1630. X        while (p < rptr->comp->startp[0]) {
  1631. X            *b++ = *p++;
  1632. X        }
  1633. X        p = rptr->replace;
  1634. X        while (*p) {
  1635. X            *b++ = *p++;
  1636. X        }
  1637. X        strcpy(b, rptr->comp->endp[0]);
  1638. X        found = 1;
  1639. X        regsub(rptr->comp, buff1, buff2);
  1640. X        strcpy(buff, buff2);
  1641. X        }
  1642. X    } while (ret && rptr->global);
  1643. X    if (found) {
  1644. X        if (rptr->print) {
  1645. X        fprintf(stderr, "%s >> %s\n", name, buff);
  1646. X        }
  1647. X        strcpy(name, buff);
  1648. X    }
  1649. X    }
  1650. X}
  1651. X
  1652. X
  1653. X/* get_disposition - get a file disposition
  1654. X *
  1655. X * DESCRIPTION
  1656. X *
  1657. X *    Get a file disposition from the user.  If the user enters 'y'
  1658. X *    the the file is processed, anything else and the file is ignored.
  1659. X *    If the user enters EOF, then the PAX exits with a non-zero return
  1660. X *    status.
  1661. X *
  1662. X * PARAMETERS
  1663. X *
  1664. X *    char    *mode    - string signifying the action to be taken on file
  1665. X *    char    *name    - the name of the file
  1666. X *
  1667. X * RETURNS
  1668. X *
  1669. X *    Returns 1 if the file should be processed, 0 if it should not.
  1670. X */
  1671. X
  1672. X#ifdef __STDC__
  1673. X
  1674. Xint get_disposition(char *mode, char *name)
  1675. X
  1676. X#else
  1677. X
  1678. Xint get_disposition(mode, name)
  1679. Xchar    *mode;
  1680. Xchar    *name;
  1681. X
  1682. X#endif
  1683. X{
  1684. X    char    ans[2];
  1685. X    char    buf[PATH_MAX + 10];
  1686. X
  1687. X    if (f_disposition) {
  1688. X    sprintf(buf, "%s %s? ", mode, name);
  1689. X    if (nextask(buf, ans, sizeof(ans)) == -1 || ans[0] == 'q') {
  1690. X        exit(0);
  1691. X    }
  1692. X    if (strlen(ans) == 0 || ans[0] != 'y') {
  1693. X        return(1);
  1694. X    } 
  1695. X    } 
  1696. X    return(0);
  1697. X}
  1698. X
  1699. X
  1700. X/* get_newname - prompt the user for a new filename
  1701. X *
  1702. X * DESCRIPTION
  1703. X *
  1704. X *    The user is prompted with the name of the file which is currently
  1705. X *    being processed.  The user may choose to rename the file by
  1706. X *    entering the new file name after the prompt; the user may press
  1707. X *    carriage-return/newline, which will skip the file or the user may
  1708. X *    type an 'EOF' character, which will cause the program to stop.
  1709. X *
  1710. X * PARAMETERS
  1711. X *
  1712. X *    char    *name        - filename, possibly modified by user
  1713. X *    int    size        - size of allowable new filename
  1714. X *
  1715. X * RETURNS
  1716. X *
  1717. X *    Returns 0 if successfull, or -1 if an error occurred.
  1718. X *
  1719. X */
  1720. X
  1721. X#ifdef __STDC__
  1722. X
  1723. Xint get_newname(char *name, int size)
  1724. X
  1725. X#else
  1726. X
  1727. Xint get_newname(name, size)
  1728. Xchar    *name;
  1729. Xint    size;
  1730. X
  1731. X#endif
  1732. X{
  1733. X    char    buf[PATH_MAX + 10];
  1734. X
  1735. X    if (f_interactive) {
  1736. X    sprintf(buf, "rename %s? ", name);
  1737. X    if (nextask(buf, name, size) == -1) {
  1738. X        exit(0);
  1739. X    }
  1740. X    if (strlen(name) == 0) {
  1741. X        return(1);
  1742. X    }
  1743. X    }
  1744. X    return(0);
  1745. X}
  1746. END_OF_replace.c
  1747. if test 6493 -ne `wc -c <replace.c`; then
  1748.     echo shar: \"replace.c\" unpacked with wrong size!
  1749. fi
  1750. # end of overwriting check
  1751. fi
  1752. if test -f ttyio.c -a "${1}" != "-c" ; then 
  1753.   echo shar: Will not over-write existing file \"ttyio.c\"
  1754. else
  1755. echo shar: Extracting \"ttyio.c\" \(6321 characters\)
  1756. sed "s/^X//" >ttyio.c <<'END_OF_ttyio.c'
  1757. X/* $Source: /u/mark/src/pax/RCS/ttyio.c,v $
  1758. X *
  1759. X * $Revision: 1.1 $
  1760. X *
  1761. X * ttyio.c - Terminal/Console I/O functions for all archive interfaces
  1762. X *
  1763. X * DESCRIPTION
  1764. X *
  1765. X *    These routines provide a consistent, general purpose interface to
  1766. X *    the user via the users terminal, if it is available to the
  1767. X *    process.
  1768. X *
  1769. X * AUTHOR
  1770. X *
  1771. X *     Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  1772. X *
  1773. X * Sponsored by The USENIX Association for public distribution. 
  1774. X *
  1775. X * Copyright (c) 1989 Mark H. Colburn.
  1776. X * All rights reserved.
  1777. X *
  1778. X * Redistribution and use in source and binary forms are permitted
  1779. X * provided that the above copyright notice is duplicated in all such 
  1780. X * forms and that any documentation, advertising materials, and other 
  1781. X * materials related to such distribution and use acknowledge that the 
  1782. X * software was developed * by Mark H. Colburn and sponsored by The 
  1783. X * USENIX Association. 
  1784. X *
  1785. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1786. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1787. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1788. X *
  1789. X * $Log:    ttyio.c,v $
  1790. X * Revision 1.1  88/12/23  18:02:39  mark
  1791. X * Initial revision
  1792. X * 
  1793. X */
  1794. X
  1795. X#ifndef lint
  1796. Xstatic char *ident = "$Id: ttyio.c,v 1.1 88/12/23 18:02:39 mark Rel $";
  1797. Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  1798. X#endif /* ! lint */
  1799. X
  1800. X
  1801. X/* Headers */
  1802. X
  1803. X#include "pax.h"
  1804. X
  1805. X
  1806. X/* open_tty - open the terminal for interactive queries
  1807. X *
  1808. X * DESCRIPTION
  1809. X *
  1810. X *     Assumes that background processes ignore interrupts and that the
  1811. X *    open() or the isatty() will fail for processes which are not
  1812. X *    attached to terminals. Returns a file descriptor or -1 if
  1813. X *    unsuccessful. 
  1814. X *
  1815. X * RETURNS
  1816. X *
  1817. X *    Returns a file descriptor which can be used to read and write
  1818. X *    directly to the user's terminal, or -1 on failure.  
  1819. X *
  1820. X * ERRORS
  1821. X *
  1822. X *    If SIGINT cannot be ignored, or the open fails, or the newly opened
  1823. X *    terminal device is not a tty, then open_tty will return a -1 to the
  1824. X *    caller.
  1825. X */
  1826. X
  1827. X#ifdef __STDC__
  1828. X
  1829. Xint open_tty(void)
  1830. X
  1831. X#else
  1832. X
  1833. Xint open_tty()
  1834. X
  1835. X#endif
  1836. X{
  1837. X    int             fd;        /* file descriptor for terminal */
  1838. X    SIG_T         (*intr)();    /* used to restore interupts if signal fails */
  1839. X
  1840. X    if ((intr = signal(SIGINT, SIG_IGN)) == SIG_IGN) {
  1841. X    return (-1);
  1842. X    }
  1843. X    signal(SIGINT, intr);
  1844. X    if ((fd = open(TTY, O_RDWR)) < 0) {
  1845. X    return (-1);
  1846. X    }
  1847. X    if (isatty(fd)) {
  1848. X    return (fd);
  1849. X    }
  1850. X    close(fd);
  1851. X    return (-1);
  1852. X}
  1853. X
  1854. X
  1855. X/* nextask - ask a question and get a response
  1856. X *
  1857. X * DESCRIPTION
  1858. X *
  1859. X *    Give the user a prompt and wait for their response.  The prompt,
  1860. X *    located in "msg" is printed, then the user is allowed to type
  1861. X *    a response to the message.  The first "limit" characters of the
  1862. X *    user response is stored in "answer".
  1863. X *
  1864. X *    Nextask ignores spaces and tabs. 
  1865. X *
  1866. X * PARAMETERS
  1867. X *
  1868. X *    char *msg    - Message to display for user 
  1869. X *    char *answer    - Pointer to user's response to question 
  1870. X *    int limit    - Limit of length for user's response
  1871. X *
  1872. X * RETURNS
  1873. X *
  1874. X *    Returns the number of characters in the user response to the 
  1875. X *    calling function.  If an EOF was encountered, a -1 is returned to
  1876. X *    the calling function.  If an error occured which causes the read
  1877. X *    to return with a value of -1, then the function will return a
  1878. X *    non-zero return status to the calling process, and abort
  1879. X *    execution.
  1880. X */
  1881. X
  1882. X#ifdef __STDC__
  1883. X
  1884. Xint nextask(char *msg, char *answer, int limit)
  1885. X
  1886. X#else
  1887. X
  1888. Xint nextask(msg, answer, limit)
  1889. Xchar           *msg;        /* message to display for user */
  1890. Xchar           *answer;        /* pointer to user's response to question */
  1891. Xint             limit;        /* limit of length for user's response */
  1892. X
  1893. X#endif
  1894. X{
  1895. X    int             idx;    /* index into answer for character input */
  1896. X    int             got;    /* number of characters read */
  1897. X    char            c;        /* character read */
  1898. X
  1899. X    if (ttyf < 0) {
  1900. X    fatal("/dev/tty Unavailable");
  1901. X    }
  1902. X    write(ttyf, msg, (uint) strlen(msg));
  1903. X    idx = 0;
  1904. X    while ((got = read(ttyf, &c, 1)) == 1) {
  1905. X    if (c == '\n') {
  1906. X        break;
  1907. X    } else if (c == ' ' || c == '\t') {
  1908. X        continue;
  1909. X    } else if (idx < limit - 1) {
  1910. X        answer[idx++] = c;
  1911. X    }
  1912. X    }
  1913. X    if (got == 0) {        /* got an EOF */
  1914. X        return(-1);
  1915. X    }
  1916. X    if (got < 0) {
  1917. X    fatal(syserr());
  1918. X    }
  1919. X    answer[idx] = '\0';
  1920. X    return(0);
  1921. X}
  1922. X
  1923. X
  1924. X/* lineget - get a line from a given stream
  1925. X *
  1926. X * DESCRIPTION
  1927. X * 
  1928. X *    Get a line of input for the stream named by "stream".  The data on
  1929. X *    the stream is put into the buffer "buf".
  1930. X *
  1931. X * PARAMETERS
  1932. X *
  1933. X *    FILE *stream        - Stream to get input from 
  1934. X *    char *buf        - Buffer to put input into
  1935. X *
  1936. X * RETURNS
  1937. X *
  1938. X *     Returns 0 if successful, -1 at EOF. 
  1939. X */
  1940. X
  1941. X#ifdef __STDC__
  1942. X
  1943. Xint lineget(FILE *stream, char *buf)
  1944. X
  1945. X#else
  1946. X
  1947. Xint lineget(stream, buf)
  1948. XFILE           *stream;        /* stream to get input from */
  1949. Xchar           *buf;        /* buffer to put input into */
  1950. X
  1951. X#endif
  1952. X{
  1953. X    int             c;
  1954. X
  1955. X    for (;;) {
  1956. X    if ((c = getc(stream)) == EOF) {
  1957. X        return (-1);
  1958. X    }
  1959. X    if (c == '\n') {
  1960. X        break;
  1961. X    }
  1962. X    *buf++ = c;
  1963. X    }
  1964. X    *buf = '\0';
  1965. X    return (0);
  1966. X}
  1967. X
  1968. X
  1969. X/* next - Advance to the next archive volume. 
  1970. X *
  1971. X * DESCRIPTION
  1972. X *
  1973. X *    Prompts the user to replace the backup medium with a new volume
  1974. X *    when the old one is full.  There are some cases, such as when
  1975. X *    archiving to a file on a hard disk, that the message can be a
  1976. X *    little surprising.  Assumes that background processes ignore
  1977. X *    interrupts and that the open() or the isatty() will fail for
  1978. X *    processes which are not attached to terminals. Returns a file
  1979. X *    descriptor or -1 if unsuccessful. 
  1980. X *
  1981. X * PARAMETERS
  1982. X *
  1983. X *    int mode    - mode of archive (READ, WRITE, PASS) 
  1984. X */
  1985. X
  1986. X#ifdef __STDC__
  1987. X
  1988. Xvoid next(int mode)
  1989. X
  1990. X#else
  1991. X
  1992. Xvoid next(mode)
  1993. Xint             mode;        /* mode of archive (READ, WRITE, PASS) */
  1994. X
  1995. X#endif
  1996. X{
  1997. X    char            msg[200];    /* buffer for message display */ 
  1998. X    char            answer[20];    /* buffer for user's answer */
  1999. X    int             ret;
  2000. X
  2001. X    close_archive();
  2002. X
  2003. X    sprintf(msg, "\
  2004. X%s: Ready for volume %u\n\
  2005. X%s: Type \"go\" when ready to proceed (or \"quit\" to abort): \07",
  2006. X           myname, arvolume + 1, myname);
  2007. X    for (;;) {
  2008. X    ret = nextask(msg, answer, sizeof(answer));
  2009. X    if (ret == -1 || strcmp(answer, "quit") == 0) {
  2010. X        fatal("Aborted");
  2011. X    }
  2012. X    if (strcmp(answer, "go") == 0 && open_archive(mode) == 0) {
  2013. X        break;
  2014. X    }
  2015. X    }
  2016. X    warnarch("Continuing", (OFFSET) 0);
  2017. X}
  2018. END_OF_ttyio.c
  2019. if test 6321 -ne `wc -c <ttyio.c`; then
  2020.     echo shar: \"ttyio.c\" unpacked with wrong size!
  2021. fi
  2022. # end of overwriting check
  2023. fi
  2024. if test -f warn.c -a "${1}" != "-c" ; then 
  2025.   echo shar: Will not over-write existing file \"warn.c\"
  2026. else
  2027. echo shar: Extracting \"warn.c\" \(5446 characters\)
  2028. sed "s/^X//" >warn.c <<'END_OF_warn.c'
  2029. X/* $Source: /u/mark/src/pax/RCS/warn.c,v $
  2030. X *
  2031. X * $Revision: 1.1 $
  2032. X *
  2033. X * warn.c - miscellaneous user warning routines 
  2034. X *
  2035. X * DESCRIPTION
  2036. X *
  2037. X *    These routines provide the user with various forms of warning
  2038. X *    and informational messages.
  2039. X *
  2040. X * AUTHOR
  2041. X *
  2042. X *     Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  2043. X *
  2044. X * Sponsored by The USENIX Association for public distribution. 
  2045. X *
  2046. X * Copyright (c) 1989 Mark H. Colburn.
  2047. X * All rights reserved.
  2048. X *
  2049. X * Redistribution and use in source and binary forms are permitted
  2050. X * provided that the above copyright notice is duplicated in all such 
  2051. X * forms and that any documentation, advertising materials, and other 
  2052. X * materials related to such distribution and use acknowledge that the 
  2053. X * software was developed * by Mark H. Colburn and sponsored by The 
  2054. X * USENIX Association. 
  2055. X *
  2056. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  2057. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  2058. X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  2059. X *
  2060. X * $Log:    warn.c,v $
  2061. X * Revision 1.1  88/12/23  18:02:40  mark
  2062. X * Initial revision
  2063. X * 
  2064. X */
  2065. X
  2066. X#ifndef lint
  2067. Xstatic char *ident = "$Id: warn.c,v 1.1 88/12/23 18:02:40 mark Rel $";
  2068. Xstatic char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  2069. X#endif /* ! lint */
  2070. X
  2071. X
  2072. X/* Headers */
  2073. X
  2074. X#include "pax.h"
  2075. X
  2076. X
  2077. X/* Function Prototypes */
  2078. X
  2079. X#ifdef __STDC__
  2080. X
  2081. Xstatic void prsize(FILE *, OFFSET);
  2082. X
  2083. X#else /* !__STDC__ */
  2084. X
  2085. Xstatic void prsize();
  2086. X
  2087. X#endif /* __STDC__ */
  2088. X
  2089. X
  2090. X/* warnarch - print an archive-related warning message and offset
  2091. X *
  2092. X * DESCRIPTION
  2093. X *
  2094. X *    Present the user with an error message and an archive offset at
  2095. X *    which the error occured.   This can be useful for diagnosing or
  2096. X *    fixing damaged archives.
  2097. X *
  2098. X * PARAMETERS
  2099. X *
  2100. X *    char     *msg    - A message string to be printed for the user.
  2101. X *    OFFSET     adjust    - An adjustment which is added to the current 
  2102. X *              archive position to tell the user exactly where 
  2103. X *              the error occurred.
  2104. X */
  2105. X
  2106. X#ifdef __STDC__
  2107. X
  2108. Xvoid warnarch(char *msg, OFFSET adjust)
  2109. X
  2110. X#else 
  2111. X
  2112. Xvoid warnarch(msg, adjust)
  2113. Xchar           *msg;
  2114. XOFFSET          adjust;
  2115. X
  2116. X#endif
  2117. X{
  2118. X    fprintf(stderr, "%s: [offset ", myname);
  2119. X    prsize(stderr, total - adjust);
  2120. X    fprintf(stderr, "]: %s\n", msg);
  2121. X}
  2122. X
  2123. X
  2124. X/* syserr - return pointer to appropriate system error message
  2125. X *
  2126. X * DESCRIPTION
  2127. X *
  2128. X *    Get an error message string which is appropriate for the setting
  2129. X *    of the errno variable.
  2130. X *
  2131. X * RETURNS
  2132. X *
  2133. X *    Returns a pointer to a string which has an appropriate error
  2134. X *    message for the present value of errno.  The error message
  2135. X *    strings are taken from sys_errlist[] where appropriate.  If an
  2136. X *    appropriate message is not available in sys_errlist, then a
  2137. X *    pointer to the string "Unknown error (errno <errvalue>)" is 
  2138. X *    returned instead.
  2139. X */
  2140. X
  2141. X#ifdef __STDC__
  2142. X
  2143. Xchar *syserr(void)
  2144. X
  2145. X#else
  2146. X
  2147. Xchar *syserr()
  2148. X
  2149. X#endif
  2150. X{
  2151. X    static char     msg[40];        /* used for "Unknown error" messages */
  2152. X
  2153. X    if (errno > 0 && errno < sys_nerr) {
  2154. X    return (sys_errlist[errno]);
  2155. X    }
  2156. X    sprintf(msg, "Unknown error (errno %d)", errno);
  2157. X    return (msg);
  2158. X}
  2159. X
  2160. X
  2161. X/* prsize - print a file offset on a file stream
  2162. X *
  2163. X * DESCRIPTION
  2164. X *
  2165. X *    Prints a file offset to a specific file stream.  The file offset is
  2166. X *    of the form "%dm+%dk+%d", where the number preceeding the "m" and
  2167. X *    the "k" stand for the number of Megabytes and the number of
  2168. X *    Kilobytes, respectivley, which have been processed so far.
  2169. X *
  2170. X * PARAMETERS
  2171. X *
  2172. X *    FILE  *stream    - Stream which is to be used for output 
  2173. X *    OFFSET size    - Current archive position to be printed on the output 
  2174. X *              stream in the form: "%dm+%dk+%d".
  2175. X *
  2176. X */
  2177. X
  2178. X#ifdef __STDC__
  2179. X
  2180. Xstatic void prsize(FILE *stream, OFFSET size)
  2181. X
  2182. X#else
  2183. X
  2184. Xstatic void prsize(stream, size)
  2185. XFILE           *stream;        /* stream which is used for output */
  2186. XOFFSET          size;        /* current archive position to be printed */
  2187. X
  2188. X#endif
  2189. X
  2190. X{
  2191. X    OFFSET          n;
  2192. X
  2193. X    if (n = (size / (1024 * 1024))) {
  2194. X    fprintf(stream, "%ldm+", n);
  2195. X    size -= n * 1024 * 1024;
  2196. X    }
  2197. X    if (n = (size / 1024)) {
  2198. X    fprintf(stream, "%ldk+", n);
  2199. X    size -= n * 1024;
  2200. X    }
  2201. X    fprintf(stream, "%ld", size);
  2202. X}
  2203. X
  2204. X
  2205. X/* fatal - print fatal message and exit
  2206. X *
  2207. X * DESCRIPTION
  2208. X *
  2209. X *    Fatal prints the program's name along with an error message, then
  2210. X *    exits the program with a non-zero return code.
  2211. X *
  2212. X * PARAMETERS
  2213. X *
  2214. X *    char     *why    - description of reason for termination 
  2215. X *        
  2216. X * RETURNS
  2217. X *
  2218. X *    Returns an exit code of 1 to the parent process.
  2219. X */
  2220. X
  2221. X#ifdef __STDC__
  2222. X
  2223. Xvoid fatal(char *why)
  2224. X
  2225. X#else
  2226. X
  2227. Xvoid fatal(why)
  2228. Xchar           *why;        /* description of reason for termination */
  2229. X
  2230. X#endif
  2231. X{
  2232. X    fprintf(stderr, "%s: %s\n", myname, why);
  2233. X    exit(1);
  2234. X}
  2235. X
  2236. X
  2237. X
  2238. X/* warn - print a warning message
  2239. X *
  2240. X * DESCRIPTION
  2241. X *
  2242. X *    Print an error message listing the program name, the actual error
  2243. X *    which occurred and an informational message as to why the error
  2244. X *    occurred on the standard error device.  The standard error is
  2245. X *    flushed after the error is printed to assure that the user gets
  2246. X *    the message in a timely fasion.
  2247. X *
  2248. X * PARAMETERS
  2249. X *
  2250. X *    char *what    - Pointer to string describing what failed.
  2251. X *    char *why    - Pointer to string describing why did it failed.
  2252. X */
  2253. X
  2254. X#ifdef __STDC__
  2255. X
  2256. Xvoid warn(char *what, char *why)
  2257. X
  2258. X#else
  2259. X
  2260. Xvoid warn(what, why)
  2261. Xchar           *what;        /* message as to what the error was */
  2262. Xchar           *why;        /* explanation why the error occurred */
  2263. X
  2264. X#endif
  2265. X{
  2266. X    fprintf(stderr, "%s: %s : %s\n", myname, what, why);
  2267. X    fflush(stderr);
  2268. X}
  2269. END_OF_warn.c
  2270. if test 5446 -ne `wc -c <warn.c`; then
  2271.     echo shar: \"warn.c\" unpacked with wrong size!
  2272. fi
  2273. # end of overwriting check
  2274. fi
  2275. echo shar: End of archive 2 \(of 6\).
  2276. cp /dev/null ark2isdone
  2277. MISSING=""
  2278. for I in 1 2 3 4 5 6 ; do
  2279.     if test ! -f ark${I}isdone ; then
  2280.     MISSING="${MISSING} ${I}"
  2281.     fi
  2282. done
  2283. if test "${MISSING}" = "" ; then
  2284.     echo You have unpacked all 6 archives.
  2285.     rm -f ark[1-9]isdone
  2286. else
  2287.     echo You still need to unpack the following archives:
  2288.     echo "        " ${MISSING}
  2289. fi
  2290. ##  End of shell archive.
  2291. exit 0
  2292.  
  2293.